/*
 * NetworkServer.cpp
 * 
 * 网络服务器实现
 */

#include "network/NetworkServer.h"
#include <muduo/base/Logging.h>

using namespace muduo;
using namespace muduo::net;

namespace framework {

NetworkServer::NetworkServer(EventLoop* loop,
                             const InetAddress& listenAddr,
                             const std::string& name)
    : loop_(loop),
      server_(new TcpServer(loop, listenAddr, name)) {
    // 设置连接回调
    server_->setConnectionCallback(
        std::bind(&NetworkServer::onConnection, this, _1));
    
    // 设置消息回调
    server_->setMessageCallback(
        std::bind(&NetworkServer::onMessage, this, _1, _2, _3));
    
    LOG_INFO << "NetworkServer created: " << name;
}

NetworkServer::~NetworkServer() {
    LOG_INFO << "NetworkServer destroyed";
}

void NetworkServer::setThreadNum(int numThreads) {
    server_->setThreadNum(numThreads);
}

void NetworkServer::start() {
    LOG_INFO << "NetworkServer starting...";
    server_->start();
}

void NetworkServer::onConnection(const TcpConnectionPtr& conn) {
    LOG_INFO << "NetworkServer - " << conn->peerAddress().toIpPort()
             << " -> " << conn->localAddress().toIpPort() << " is "
             << (conn->connected() ? "UP" : "DOWN");
    
    if (conn->connected()) {
        // 创建会话
        auto session = sessionManager_.addSession(conn);
        session->setState(SessionState::Connected);
        
        // 回调用户
        if (sessionConnectedCallback_) {
            sessionConnectedCallback_(session);
        }
    } else {
        // 查找会话
        auto session = sessionManager_.getSessionByConn(conn);
        if (session) {
            session->setState(SessionState::Disconnected);
            
            // 回调用户
            if (sessionDisconnectedCallback_) {
                sessionDisconnectedCallback_(session);
            }
            
            // 移除会话
            sessionManager_.removeSession(session->sessionId());
        }
    }
}

void NetworkServer::onMessage(const TcpConnectionPtr& conn,
                              Buffer* buf,
                              Timestamp time) {
    auto session = sessionManager_.getSessionByConn(conn);
    if (session) {
        // 更新心跳
        session->updateHeartbeat();
        
        // 回调用户
        if (sessionMessageCallback_) {
            sessionMessageCallback_(session, buf, time);
        }
    } else {
        LOG_WARN << "Message from unknown connection: " << conn->name();
    }
}

void NetworkServer::send(uint64_t sessionId, const std::string& data) {
    auto session = sessionManager_.getSession(sessionId);
    if (session) {
        session->send(data);
    }
}

void NetworkServer::send(uint64_t sessionId, const void* data, size_t len) {
    auto session = sessionManager_.getSession(sessionId);
    if (session) {
        session->send(data, len);
    }
}

void NetworkServer::broadcast(const std::string& data) {
    sessionManager_.foreach([&data](const SessionPtr& session) {
        session->send(data);
    });
}

void NetworkServer::broadcast(const void* data, size_t len) {
    sessionManager_.foreach([data, len](const SessionPtr& session) {
        session->send(data, len);
    });
}

void NetworkServer::closeSession(uint64_t sessionId) {
    auto session = sessionManager_.getSession(sessionId);
    if (session) {
        session->close();
    }
}

SessionPtr NetworkServer::getSession(uint64_t sessionId) {
    return sessionManager_.getSession(sessionId);
}

} // namespace framework

